﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Common.Net
{
    public class Utils
    {
        /// <summary>
        /// 返回 HTML 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>编码结果</returns>
        public static string HtmlEncode(string str)
        {
            return HttpUtility.HtmlEncode(str);
        }

        /// <summary>
        /// 返回 HTML 字符串的解码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>解码结果</returns>
        public static string HtmlDecode(string str)
        {
            return HttpUtility.HtmlDecode(str);
        }

        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>编码结果</returns>
        public static string UrlEncode(string str)
        {
            return HttpUtility.UrlEncode(str);
        }

        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>解码结果</returns>
        public static string UrlDecode(string str)
        {
            return HttpUtility.UrlDecode(str);
        }

        #region 读取或写入cookie
        /// <summary>
        /// 写cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strValue">值</param>
        public static void WriteCookie(string strName, string strValue)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[strName];
            if (cookie == null)
            {
                cookie = new HttpCookie(strName);
            }
            cookie.Value = UrlEncode(strValue);
            HttpContext.Current.Response.AppendCookie(cookie);
        }

        /// <summary>
        /// 写cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strValue">值</param>
        public static void WriteCookie(string strName, string key, string strValue)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[strName];
            if (cookie == null)
            {
                cookie = new HttpCookie(strName);
            }
            cookie[key] = UrlEncode(strValue);
            HttpContext.Current.Response.AppendCookie(cookie);
        }

        /// <summary>
        /// 写cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strValue">值</param>
        public static void WriteCookie(string strName, string key, string strValue, int expires)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[strName];
            if (cookie == null)
            {
                cookie = new HttpCookie(strName);
            }
            cookie[key] = UrlEncode(strValue);
            cookie.Expires = DateTime.Now.AddMinutes(expires);
            HttpContext.Current.Response.AppendCookie(cookie);
        }

        /// <summary>
        /// 写cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strValue">值</param>
        /// <param name="strValue">过期时间(分钟)</param>
        public static void WriteCookie(string strName, string strValue, int expires)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[strName];
            if (cookie == null)
            {
                cookie = new HttpCookie(strName);
            }
            cookie.Value = UrlEncode(strValue);
            if (expires != -1)
            {
                cookie.Expires = DateTime.Now.AddMinutes(expires);
            }
            HttpContext.Current.Response.AppendCookie(cookie);
        }

        /// <summary>
        /// 读cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>cookie值</returns>
        public static string GetCookie(string strName)
        {
            if (HttpContext.Current.Request.Cookies != null && HttpContext.Current.Request.Cookies[strName] != null)
                return UrlDecode(HttpContext.Current.Request.Cookies[strName].Value.ToString());
            return "";
        }

        /// <summary>
        /// 读cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>cookie值</returns>
        public static string GetCookie(string strName, string key)
        {
            if (HttpContext.Current.Request.Cookies != null && HttpContext.Current.Request.Cookies[strName] != null && HttpContext.Current.Request.Cookies[strName][key] != null)
                return UrlDecode(HttpContext.Current.Request.Cookies[strName][key].ToString());

            return "";
        }
        /// <summary>
        /// 移除指定的Cookie
        /// </summary>
        /// <param name="cookieName"></param>
        public static void RemoveCookie(string cookieName)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
            if (cookie == null)
            {
                cookie = new HttpCookie(cookieName);
            }
            cookie.Value = null;
            cookie.Expires = DateTime.Now.AddDays(-1);
            HttpContext.Current.Response.AppendCookie(cookie);

            //HttpContext.Current.Response.Cookies.Remove(HttpUtility.UrlEncode(cookieName));
            //HttpContext.Current.Response.Cookies[HttpUtility.UrlEncode(cookieName)].Expires = DateTime.Now.AddDays(-1);
        }
        /// <summary>
        /// 移除cookie中指定的键，若是最后一个键则移除这个cookie
        /// </summary>
        /// <param name="cookieName"></param>
        /// <param name="keyName"></param>
        public static void RemoveCookie(string cookieName, string keyName)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
            if (cookie != null)
            {
                if (cookie.Values.Count > 0)
                {
                    if (cookie.Values.Count == 1)
                    {
                        //若是最后一个键则移除这个cookie,否则会多出一个空值
                        cookie.Values.Remove(HttpUtility.UrlEncode(keyName));
                        cookie.Expires = DateTime.Now.AddDays(-1);
                    }
                    else
                    {
                        cookie.Values.Remove(HttpUtility.UrlEncode(keyName));
                    }
                    HttpContext.Current.Response.Cookies.Add(cookie);
                }
            }
        }
        #endregion

        #region 下载或打开文件
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="serverfilepath"></param>
        /// <param name="filename"></param>
        public static void ToDownload(string serverfilepath, string filename)
        {
            if (!string.IsNullOrEmpty(serverfilepath))
            {
                try
                {
                    HttpContext.Current.Response.Clear();
                    HttpContext.Current.Response.ClearContent();
                    HttpContext.Current.Response.ClearHeaders();
                    HttpContext.Current.Response.ContentType = "application/x-zip-compressed";
                    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + UTF_FileName(filename) + "\";");
                    HttpContext.Current.Response.TransmitFile(serverfilepath);
                    HttpContext.Current.Response.End();
                }
                catch (Exception)
                {
                    //HttpContext.Current.Response.Write("<script>alert('文件已经不存在！')</script>");
                    //HttpContext.Current.Response.End();
                }
            }
            else
            {
                //HttpContext.Current.Response.Write("<script>alert('文件已经不存在！')</script>");
                //HttpContext.Current.Response.End();
            }
        }

        public static void ToDownload(Stream fileStream, string filename)
        {
            if (fileStream != null)
            {
                long fileSize = fileStream.Length;
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.ClearHeaders();
                HttpContext.Current.Response.Buffer = false;
                HttpContext.Current.Response.ContentType = "application/octet-stream";
                HttpContext.Current.Response.AddHeader("Connection", "Keep-Alive");
                HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + UTF_FileName(filename) + "\";");
                ////attachment --- 作为附件下载
                ////inline --- 在线打开
                HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
                byte[] fileBuffer = new byte[fileSize];
                fileStream.Read(fileBuffer, 0, (int)fileSize);
                HttpContext.Current.Response.BinaryWrite(fileBuffer);
                fileStream.Close();
                HttpContext.Current.Response.Flush();
                HttpContext.Current.Response.End();
            }
            else
            {
                //HttpContext.Current.Response.Write("<script>alert('文件已经不存在！')</script>");
                //HttpContext.Current.Response.End();
            }
        }

        public static void ToDownload(byte[] fileBuffer, string filename)
        {
            if (fileBuffer != null)
            {
                long fileSize = fileBuffer.Length;
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.ClearHeaders();
                HttpContext.Current.Response.Buffer = false;
                HttpContext.Current.Response.ContentType = "application/octet-stream";
                HttpContext.Current.Response.AddHeader("Connection", "Keep-Alive");
                HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + UTF_FileName(filename) + "\";");
                ////attachment --- 作为附件下载
                ////inline --- 在线打开
                HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
                HttpContext.Current.Response.BinaryWrite(fileBuffer);
                HttpContext.Current.Response.Flush();
                HttpContext.Current.Response.End();
            }
            else
            {
                //HttpContext.Current.Response.Write("<script>alert('文件已经不存在！')</script>");
                //HttpContext.Current.Response.End();
            }
        }

        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="serverfilepath"></param>
        /// <param name="filename"></param>
        public static void ToOpen(string serverfilepath, string filename)
        {
            FileStream fileStream = new FileStream(serverfilepath, FileMode.Open);
            ToOpen(fileStream, filename);
        }

        public static void ToOpen(Stream fileStream, string filename)
        {
            long fileSize = fileStream.Length;
            HttpContext.Current.Response.ContentType = "application/octet-stream";
            HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + UTF_FileName(filename) + "\";");
            HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
            byte[] fileBuffer = new byte[fileSize];
            fileStream.Read(fileBuffer, 0, (int)fileSize);
            HttpContext.Current.Response.BinaryWrite(fileBuffer);
            fileStream.Close();
            HttpContext.Current.Response.End();
        }

        public static string UTF_FileName(string filename)
        {
            return HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8);
        }

        /// <summary>
        /// 下载文件数据流
        /// </summary>
        /// <param name="serverfilepath"></param>
        public static void DownLoadStreamFile(string serverfilepath)
        {
            int blocksize = 1024 * 100;
            byte[] buffer = new byte[blocksize];
            byte[] fileHeader = new byte[101];

            int startindex = 0;
            int bytesread = 0;
            int bytesfinish = 0;
            int filesize = 0;
            string headerText = string.Empty;
            BinaryReader bReader = null;

            bReader = new BinaryReader(File.OpenRead(serverfilepath));
            filesize = Convert.ToInt32(bReader.BaseStream.Length);

            while (bytesfinish < filesize)
            {
                if (bytesfinish + blocksize < filesize)
                    bytesread = bReader.Read(buffer, startindex, blocksize);
                else
                    bytesread = bReader.Read(buffer, startindex, filesize - bytesfinish);

                bytesfinish += bytesread;
                HttpContext.Current.Response.OutputStream.Write(buffer, 0, bytesread);
            }
            bReader.Close();
            HttpContext.Current.Response.End();
        }


        #endregion
    }
}
